package com.ptu.spzx.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ptu.spzx.common.exception.ptuException;
import com.ptu.spzx.model.dto.h5.UserLoginDto;
import com.ptu.spzx.model.dto.h5.UserRegisterDto;
import com.ptu.spzx.model.dto.system.AssginStuDeptDto;
import com.ptu.spzx.model.entity.system.SysDept;
import com.ptu.spzx.model.entity.user.UserInfo;
import com.ptu.spzx.model.vo.common.Result;
import com.ptu.spzx.model.vo.common.ResultCodeEnum;
import com.ptu.spzx.model.vo.h5.UserInfoVo;
import com.ptu.spzx.user.mapper.SysDeptMapper;
import com.ptu.spzx.user.mapper.UserInfoMapper;
import com.ptu.spzx.user.service.UserInfoService;
import com.ptu.utils.AuthContextUtil;
import org.apache.catalina.User;
import org.apache.xmlbeans.impl.xb.xsdschema.Attribute;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Override
    public void register(UserRegisterDto userRegisterDto) {
        //1  userRegisterDto获取数据
        String username = userRegisterDto.getUsername();
        String password = userRegisterDto.getPassword();
        String nickName = userRegisterDto.getNickName();
        String code = userRegisterDto.getCode();
        //2 验证码校验
        //2.1 从redis获取发送验证码
        String redisCode = redisTemplate.opsForValue().get(username);;
        //2.2 获取输入的验证码，进行比对
        if(!redisCode.equals(code)){
            throw new ptuException(ResultCodeEnum.VALIDATECODE_ERROR);
        }
        //3 校验用户名不能重复
        UserInfo userInfo = userInfoMapper.selectByUsername(username);
        if(userInfo!=null){ //存在相同的用户名
            throw new ptuException(ResultCodeEnum.USER_NAME_IS_EXISTS);
        }
        //4 封装需要添加的数据，调用方法添加数据库 预防空指针异常
        userInfo = new UserInfo();
        userInfo.setUsername(username);
        userInfo.setNickName(nickName);
        userInfo.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        userInfo.setPhone(username);
        userInfo.setStatus(1);
        userInfo.setSex(0);
        userInfo.setAvatar("http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132");
        userInfoMapper.save(userInfo);
        //5 删除发送验证码
        redisTemplate.delete(username);
    }

    @Override
    public String login(UserLoginDto userLoginDto) {
        //1,dto获取用户名和密码
        String username = userLoginDto.getUsername();
        String password = userLoginDto.getPassword();

        //2，根据用户名查询数据库，得到用户信息
        UserInfo userInfo = userInfoMapper.selectByUsername(username);
        if(userInfo==null){
            throw new ptuException(ResultCodeEnum.LOGIN_ERROR);
        }
        //3 比较密码是否一致
        String database_password = userInfo.getPassword();
        String md5_password = DigestUtils.md5DigestAsHex(password.getBytes());
        if(!database_password.equals(md5_password)){
            throw new ptuException(ResultCodeEnum.LOGIN_ERROR);
        }
        //4 校验用户是否禁用
        if(userInfo.getStatus()==0){
            throw new ptuException(ResultCodeEnum.ACCOUNT_STOP);
        }
        //5 生成token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //6 把用户信息放到redis里面去
        redisTemplate.opsForValue().set("user:spzx"+token,
                JSON.toJSONString(userInfo),
                30, TimeUnit.DAYS);
        //7 返回token
        return token;
    }

    @Override
    public UserInfoVo getCurrentUserInfo(String token) {
        //从redis里面根据用户获取用户信息
//        String userJson = redisTemplate.opsForValue().get("user:spzx" + token);
//        if(!StringUtils.hasText(userJson)){
//            throw new ptuException(ResultCodeEnum.LOGIN_ERROR);
//        }
//        UserInfo userInfo = JSON.parseObject(userJson, UserInfo.class);

        //从ThreadLocal里面获取用户信息
        UserInfo userInfo = AuthContextUtil.getUserInfo();
        UserInfoVo userInfoVo=new UserInfoVo();
        BeanUtils.copyProperties(userInfo,userInfoVo);
        return userInfoVo;
    }

    @Override
    public void setClassId(List<String> stuIds,String className) {
        for(String stu:stuIds){
            userInfoMapper.setClassId(stu,className);
        }
    }

    @Override
    public UserInfo getStu(String stuId) {
        if(stuId==null){
            throw new ptuException(ResultCodeEnum.STU_LESS);
        }
        UserInfo userInfo=userInfoMapper.getStu(stuId);
        return userInfo;
    }

    @Override
    public List<UserInfo> getStuList(String className) {
        if(className==null){
            throw new ptuException(ResultCodeEnum.CLASS_LESS);
        }
        List<UserInfo> userInfos=userInfoMapper.getStus(className);
        if(userInfos==null){
            throw new ptuException(ResultCodeEnum.DATA_ERROR);
        }
        return userInfos;
    }

    @Override
    public void doAssignDept(AssginStuDeptDto assginStuDeptDto) {
        String stuId = assginStuDeptDto.getStuId();
        Long deptId = assginStuDeptDto.getDeptId();
        List<SysDept> sysDepts = sysDeptMapper.selectAll();
        String speciality=null;
        Long parentId;
        String department=null;
        for(SysDept sysDept : sysDepts){
            if(deptId == sysDept.getId()){
                speciality = sysDept.getDeptName();
                parentId=sysDept.getParentId();
                department = sysDeptMapper.selectParentName(parentId);
            }
        }
        Map<String, Object> params = new HashMap<>();
        try {
            params.put("department", department);
            params.put("speciality", speciality);
            params.put("stuId", stuId);
        } catch (Exception e) {
            throw new ptuException(ResultCodeEnum.DATA_ERROR);
        }
        userInfoMapper.doAssign(params);
    }

    @Override
    public List<String> getStuListByClass(String className) {
        List<String> stuListByClass = userInfoMapper.getStuListByClass(className);
        return stuListByClass;
    }

    @Override
    public void setClaaNull(String className) {
        userInfoMapper.setClaaNull(className);
    }

    @Override
    public PageInfo<UserInfo> getStuListByClassName(List<String> classNames,Integer pageNum,Integer pageSize) {
        LambdaQueryWrapper<UserInfo> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(UserInfo::getClassName,classNames);
        PageHelper.startPage(pageNum,pageSize);
        List<UserInfo> userInfos = userInfoMapper.selectList(lambdaQueryWrapper);
        PageInfo<UserInfo> userInfoPageInfo=new PageInfo<>(userInfos);
        return userInfoPageInfo;
    }

    @Override
    public List<UserInfo> getStuListByAllClassName(List<String> stuIds) {
        List<UserInfo> userInfoList=new ArrayList<>();
        for(String stuId:stuIds){
            List<UserInfo> userInfos = userInfoMapper.getStuListByStuId(stuId);
            userInfoList.addAll(userInfos);
        }
        return userInfoList;
    }
}
